/*
 * Java学习论坛
 * Copyright 2017 (C) All Rights Reserved.
 */
package cn.studyjava.verify.config.runner;

import java.io.File;
import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import cn.studyjava.verify.common.Const;
import cn.studyjava.verify.common.enums.VerifyEnum;
import cn.studyjava.verify.service.IGenerateCodeService;
import cn.studyjava.verify.service.impl.VerifyServiceImpl;
import cn.studyjava.verify.util.FileUtil;
import cn.studyjava.verify.util.ThreadPoolExecutorUtil;

/**
 * <p>
 * Description: 项目加载成功执行一次
 * </p>
 * 
 * @author: zsljava
 * @version 1.0.0
 * <p>
 * History:
 * -----------------------------------------------
 * @Date: 2017年8月7日 下午4:55:40
 * @author: zsljava
 * @version 1.0.0
 * @OP: Create
 * -----------------------------------------------
 * </p>
 *
 * @since
 * @see
 */
@Component
public class InitRunner implements CommandLineRunner{
	
	private Logger log = LoggerFactory.getLogger(InitRunner.class);
	
	/**
	 * 重新初始化目录，会将resource/defverify目录下的图片覆盖base目录	
	 */
	@Value("${folder.initDir}")
	private boolean initDir;
	
	/**
	 * base目录
	 */
	@Value("${folder.baseDir}")
	private String baseDir;
	
	/**
	 * 原图目录
	 */
	@Value("${folder.artworkDir}")
	private String artworkDir;
	
	/**
	 * 原修复图的目录
	 */
	@Value("${folder.repairDir}")
	private String repairDir;
	
	/**
	 * 临界值  redis中验证图片少于criticalityValue，生成createValue张
	 */
	@Value("${verify.img.criticalityValue}")
	private int criticalityValue; 
	
	/**
	 * 临界值  redis中验证图片少于criticalityValue，生成createValue张
	 */
	@Value("${verify.img.createValue}")
	private int createValue; 
	
	@Autowired
	private StringRedisTemplate redisTemplate;
	
	@Autowired
	private IGenerateCodeService generateCodeService;

	/**
	 * @Title: run
	 * @Description: 项目启动加载一起
	 * @param args
	 * @throws Exception
	 * @see org.springframework.boot.CommandLineRunner#run(java.lang.String[])
	 */
	@Override
	public void run(String... args) throws Exception {
		initVerify(); // 初始化验证目录
		
		initVerifyCode(); // 如果验证码数量小于10 则重新生成一批
	}


	/**
	 * @Title: initVerifyCode
	 * @Description: 如果验证码数量小于10 则重新生成一批
	 * @return: void
	 */
	private void initVerifyCode() {
		// 获取集合大小
		Long size = redisTemplate.opsForSet().size(Const.VERIFY_CODE_SET);
		
		// 如果小于临界值则生成createValue 张验证码
		if(size <= criticalityValue){
			ThreadPoolExecutorUtil threadPoolExecutorUtil = new ThreadPoolExecutorUtil();
			for (int i = 0; i < 10; i++) {
				threadPoolExecutorUtil.execute(()->{
					log.debug("验证码少于{}张，执行生成命令，生成{}", criticalityValue, createValue);
					generateCodeService.generate(createValue/10);
				});
			}
		}
	}

	
	private void initVerify(){
		File f1 = new File(baseDir + artworkDir);
		File f2 = new File(baseDir.concat(repairDir));
		if(initDir){
			log.debug("重新生成图片源文件目录,同时清空redis缓存服务器");
			f1.delete();
			f2.delete();
			try {
				redisTemplate.execute(new RedisCallback<Object> (){
					@Override
					public Object doInRedis(RedisConnection redis) throws DataAccessException {
						redis.flushDb();
						return null;
					}
					
				});
			} catch (Exception e) {
				log.error(VerifyEnum.SERVICE_REIDS_CONNECTION_FAIL.getMsg());
				System.exit(0);
			}
			
			
		}
		String dir = VerifyServiceImpl.class.getResource("/").getPath();
		if(!f1.exists()){
			log.debug("--------------初始化验证原图目录----------------");
			f1.mkdirs();
			try {
				FileUtil.copyFolder(new File(dir.concat("defverify/artwork")), f1);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		if(!f2.exists()){
			log.debug("--------------初始化修复原图目录----------------");
			f2.mkdirs();
			try {
				FileUtil.copyFolder(new File(dir.concat("defverify/repair")), f2);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
}
